#ifndef _HTTPREQUEST_HPP_
#define _HTTPREQUEST_HPP_

#include "jhdefs.hpp"
#include "types.hpp"
#include "net/HTTPMessage.hpp"
#include "net/NameValueCollection.hpp"
#include <istream>
#include <ostream>
#include <string>

NET_NAMESPACE_BEGIN

class CHTTPRequest : public CHTTPMessage
{
public:
	CHTTPRequest();
	CHTTPRequest(const std::string& version);
	CHTTPRequest(const std::string& method, const std::string& uri);
	CHTTPRequest(const std::string& method, const std::string& uri, const std::string& version);
	virtual ~CHTTPRequest();

	void setMethod(const std::string& method);
	const std::string& getMethod() const;

	void setURI(const std::string& uri);
	const std::string& getURI() const;

	void setHost(const std::string& host);
	void setHost(const std::string& host, UInt16 port);

	const std::string& getHost() const;

	void setCookies(const CNameValueCollection& cookies);
	void getCookies(CNameValueCollection& cookies) const;

	bool hasCredentials() const;
	void getCredentials(std::string& scheme, std::string& authInfo) const;
	void setCredentials(const std::string& scheme, const std::string& authInfo);
	bool hasProxyCredentials() const;
	void getProxyCredentials(std::string& scheme, std::string& authInfo) const;
	void setProxyCredentials(const std::string& scheme, const std::string& authInfo);

	void write(std::ostream& ostr) const;
	void read(std::istream& istr);

	static const std::string HTTP_GET;
	static const std::string HTTP_HEAD;
	static const std::string HTTP_PUT;
	static const std::string HTTP_POST;
	static const std::string HTTP_OPTIONS;
	static const std::string HTTP_DELETE;
	static const std::string HTTP_TRACE;
	static const std::string HTTP_CONNECT;

	static const std::string HOST;
	static const std::string COOKIE;
	static const std::string AUTHORIZATION;
	static const std::string PROXY_AUTHORIZATION;
	static const std::string UPGRADE;

protected:
	void getCredentials(const std::string& header, std::string& scheme, std::string& authInfo) const;
	void setCredentials(const std::string& header, const std::string& scheme, const std::string& authInfo);
	
private:
	enum Limits
	{
		MAX_METHOD_LENGTH  = 32,
		MAX_URI_LENGTH     = 16384,
		MAX_VERSION_LENGTH = 8
	};

	std::string m_method;
	std::string m_uri;

	CHTTPRequest(const CHTTPRequest&);
	CHTTPRequest& operator = (const CHTTPRequest&);
};


NET_NAMESPACE_END

#endif
